import { Inject, Provide } from '@midwayjs/core';
import { BaseService } from '../../../common/base.service';
import { BaseSysRole } from '../entity/role';
import { InjectDataSource, InjectEntityModel } from '@midwayjs/typeorm';
import { DataSource, Repository } from 'typeorm';
import { RedisService } from '@midwayjs/redis';
import { RoleDTO } from '../dto/role';
import { BaseSysRoleMenu } from '../entity/role.menu';

@Provide()
export class RoleService extends BaseService<BaseSysRole> {
  @InjectEntityModel(BaseSysRole)
  roleModel: Repository<BaseSysRole>;

  @InjectEntityModel(BaseSysRoleMenu)
  roleMenuModel: Repository<BaseSysRoleMenu>;

  @Inject()
  redisService: RedisService;

  @InjectDataSource()
  defaultDataSource: DataSource;

  getModel(): Repository<BaseSysRole> {
    return this.roleModel;
  }
  async createRole(roleDTO: RoleDTO) {
    const entity = new BaseSysRole();
    Object.assign(entity, roleDTO.toEntity());
    await this.defaultDataSource.transaction(async manager => {
      await manager.save(BaseSysRole, entity)
      await manager.save(
        BaseSysRoleMenu,
        roleDTO.menuList.map(menuId => {
          const roleMenu = new BaseSysRoleMenu();
          roleMenu.roleId = entity.id;
          roleMenu.menuId = +menuId;
          return roleMenu;
        })
      );
    })

    return entity
  }
  async editRole(roleDTO: RoleDTO) {
    const { id } = roleDTO;
    const entity = await this.roleModel.findOneBy({ id })
    Object.assign(entity, roleDTO);
    const roleMenuMap = await this.roleMenuModel.findBy({
      roleId: roleDTO.id,
    });
    await this.defaultDataSource.transaction(async manager => {
      await manager.remove(BaseSysRoleMenu, roleMenuMap);
      await manager.save(
        BaseSysRoleMenu,
        roleDTO.menuList.map(menuId => {
          const roleMenu = new BaseSysRoleMenu();
          roleMenu.roleId = entity.id;
          roleMenu.menuId = +menuId;
          return roleMenu;
        })
      );
      await manager.save(BaseSysRole, entity)
    })
    return entity;
  }
  async deleteRole(id: number) {
    const entity = await this.roleModel.findOneBy({ id });
    const roleMenuMap = await this.roleMenuModel.findBy({
      roleId: id,
    });
    await this.defaultDataSource.transaction(async manager => {
      await manager.remove(BaseSysRoleMenu, roleMenuMap);
      await manager.remove(entity)
    })
  }
}
